package com.community.common.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.community.common.mapper.CameraMapper;
import com.community.common.mapper.CommunityMapper;
import com.community.common.mapper.OwnerHouseMapper;
import com.community.common.mapper.UserPermissionMapper;
import com.community.common.pojo.Constant;
import com.community.common.pojo.PageRequest;
import com.community.common.pojo.domain.Camera;
import com.community.common.pojo.domain.UserPermission;
import com.community.common.pojo.dto.CameraCondition;
import com.community.common.pojo.response.MyResponse;
import com.community.common.util.CommonUtil;
import com.github.pagehelper.PageHelper;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.swing.filechooser.FileSystemView;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.google.zxing.client.j2se.MatrixToImageWriter.writeToFile;

/**
 * <p>
 * 相机表 服务实现类
 * </p>
 *
 * @author superman
 * @since 2020-08-02
 */
@Slf4j
@Service
public class CameraService {

    @Resource
    private CommunityMapper communityMapper;
    @Resource
    private UserPermissionMapper userPermissionMapper;
    @Resource
    private CameraMapper cameraMapper;
    @Resource
    private OwnerHouseMapper ownerHouseMapper;

    public MyResponse add(Camera camera) {
        camera.setId(String.valueOf(CommonUtil.getId()));
        camera.setCreateTime(LocalDateTime.now());
        camera.setUpdateTime(LocalDateTime.now());
        String communityId = camera.getCommunityId();
        String name = communityMapper.selectById(communityId).getName();
        camera.setCommunityName(name);
        int insert = cameraMapper.insert(camera);
        if (insert == 1) {
            //将当前小区下面所有审核通过的人 添加到相机里面
            List<UserPermission> userPermissions = userPermissionMapper.selectByCommunityIdToInsert(communityId);
            for (UserPermission userPermission : userPermissions) {
                userPermission.setId(CommonUtil.getIdStr()).setCurrentAllow(0)
                        .setCommandStatus(Constant.COMMAND_INIT).setCommunityId(communityId)
                        .setCreateTime(LocalDateTime.now()).setUpdateTime(LocalDateTime.now());
                userPermissionMapper.insert(userPermission);
            }
            return MyResponse.success();
        }
        return MyResponse.fail();
    }


    public boolean delete(List<Long> ids) {
        if (ids != null && ids.size() > 0) {
            for (Long id : ids) {
                cameraMapper.deleteById(id);
                LambdaQueryWrapper<UserPermission> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(UserPermission::getCameraId, id);
                List<UserPermission> userPermissionList = userPermissionMapper.selectList(queryWrapper);
                if (CollectionUtils.isNotEmpty(userPermissionList)) {
                    userPermissionMapper.deleteBatchIds(
                            userPermissionList.stream().map(UserPermission::getId).collect(Collectors.toList()));
                }
                return true;
            }
        }
        return false;
    }


    public boolean edit(Camera camera) {
        Camera cameraDb = cameraMapper.selectById(camera.getId());
        if (!StringUtils.equals(camera.getSn(), cameraDb.getSn())) {
            //相机sn修改后 需要重置原来这个相机下发的权限
            LambdaQueryWrapper<UserPermission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(UserPermission::getCameraId, camera.getId());
            List<UserPermission> userPermissions = userPermissionMapper.selectList(queryWrapper);
            if (CollectionUtils.isNotEmpty(userPermissions)) {
                for (UserPermission userPermission : userPermissions) {
                    if (userPermission.getEndTime().isAfter(LocalDateTime.now())) {
                        userPermission.setCurrentAllow(0).setTargetAllow(1).setCommandStatus(Constant.COMMAND_INIT);
                    }
                }
            }
        }
        camera.setUpdateTime(LocalDateTime.now());
        int i = cameraMapper.updateById(camera);
        return true;
    }


    public Camera getById(Long id) {
        return cameraMapper.selectById(id);
    }


    public List<Camera> getByCommunityId(String communityId) {
        LambdaQueryWrapper<Camera> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Camera::getCommunityId, communityId);
        return cameraMapper.selectList(queryWrapper);
    }


    public Camera getBySn(String sn) {
        LambdaQueryWrapper<Camera> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Camera::getSn, sn);
        return cameraMapper.selectOne(queryWrapper);
    }


    public List<Camera> queryByPage(PageRequest<CameraCondition> pageRequest, String communityId) {
        CameraCondition condition = pageRequest.getCondition();
        LambdaQueryWrapper<Camera> wrapper = new LambdaQueryWrapper<>();
        if (condition != null) {
            if (StringUtils.isNotBlank(condition.getSn())) {
                wrapper.like(Camera::getSn, condition.getSn());
            }
        }
        if (communityId != null) {
            wrapper.eq(Camera::getCommunityId, communityId);
        }
        PageHelper.startPage(pageRequest.getCurrentPage(), pageRequest.getPageSize());
        return cameraMapper.selectList(wrapper);
    }

    public boolean createQRCode(String sn, Camera bySn) {
        //  要生成二维码的链接
        String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf43b9ebf8b7e67cc&redirect_uri=http://www.kehuitewlw.com/cm/zhihui/?sn=" + sn + "&response_type=code&scope=snsapi_userinfo&state=123&connect_redirect=1#wechat_redirect";
        //	指定路径：D:\User\Desktop\testQrcode
        String path = FileSystemView.getFileSystemView().getHomeDirectory() + File.separator + "qrcode";
        //	指定二维码图片名字
        String fileName = bySn.getCommunityName() + bySn.getDoor() + "__" + sn + ".jpg";
        try {
            createQrCode(url, path, fileName);
        } catch (Exception e) {
            return false;
        }
        return true;

    }

    private void createQrCode(String url, String path, String fileName) {
        try {
            Map<EncodeHintType, String> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, 400, 400, hints);
            File file = new File(path, fileName);
            if (file.exists() || ((file.getParentFile().exists() || file.getParentFile().mkdirs()) && file.createNewFile())) {
                writeToFile(bitMatrix, "jpg", file);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        if (!ImageIO.write(image, format, file)) {
            throw new IOException("Could not write an image of format " + format + " to " + file);
        }
    }


    private static final int BLACK = 0xFF000000;
    private static final int WHITE = 0xFFFFFFFF;

    private static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.getHeight();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
            }
        }
        return image;
    }

    /**
     * 校验相机sn
     * @param sn
     * @return
     */
    public boolean checkSn(String sn) {
        LambdaQueryWrapper<Camera> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Camera::getSn,sn);
        List<Camera> cameras = cameraMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(cameras)) {
            return true;
        }
        return false;
    }

}
